package
{
	import flash.display.*;
	import flash.events.*;
	import flash.external.*;
	import flash.net.*;
	import flash.text.*;
	import flash.utils.*;

	public class PandaUpload extends Sprite
	{
		private var params:Object = root.loaderInfo.parameters;

		private var loader:Loader = new Loader();
		private var text:TextField = new TextField();
		private var button:Sprite = new Sprite();
		private var browser:FileReferenceList = new FileReferenceList();

		private var idCounter:Number = 0;
		private var uploadingFiles:Dictionary = new Dictionary();

		public static function main():void
		{
			new PandaUpload();
		}

		public function PandaUpload() {		
			configStage();

			loadImage();
			configText();
			configButton();
			configBrowser();

			configCancel();
		}

		private function configStage():void {
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;

			stage.addChild(loader);
			stage.addChild(text);
			stage.addChild(button);
		}

		private function loadImage():void {
			loader.load(new URLRequest(params.image));

			stage.addEventListener(MouseEvent.MOUSE_OVER, function():void {
				loader.y = - params.height;
			});
			stage.addEventListener(MouseEvent.MOUSE_OUT, function():void {
				loader.y = 0;
			});
		}

		private function configText():void {
			text.antiAliasType = AntiAliasType.ADVANCED;
			text.cacheAsBitmap = true;

			text.x = params.textLeft;
			text.y = params.textTop;
			text.htmlText = params.text

			var style:StyleSheet = new StyleSheet();
			style.parseCSS(params.textStyle);
			text.styleSheet = style;
		}

		private function configButton():void {
			button.graphics.beginFill(0xFFFFFF, 0);
			button.graphics.drawRect(0, 0, 1, 1);
			button.graphics.endFill();
			button.buttonMode = true;
			button.useHandCursor = true;

			button.width = params.width;
			button.height = params.height;

			button.addEventListener(MouseEvent.CLICK, function():void {
				loader.y = 0;
				browser.browse();
			});
		}

		private function configBrowser():void {
			browser.addEventListener(Event.SELECT, function():void {
				var files:Array = new Array();
				eachFile(function(file:FileReference, i:Number):void {
					files.push({ id: idCounter++, name: file.name, size: file.size });
				});

				if (call("onUpload", { files: files } )) {
					upload(files);
				}
			});
		}

		private function configCancel():void {
			ExternalInterface.addCallback("cancel", function(id:Number):void {
				uploadingFiles[id].cancel();
				delete uploadingFiles[id];
			});
		}

		private function upload(files:Array):void {
			eachFile(function(file:FileReference, i:Number):void {
				var id:Number = files[i].id;
				uploadingFiles[id] = file;

				file.addEventListener(ProgressEvent.PROGRESS, function(e:ProgressEvent):void {
					call("onProgress", { id: id, loaded: e.bytesLoaded, total: e.bytesTotal });
				});

				file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, function(e:DataEvent):void {
					delete uploadingFiles[id];
					call("onComplete", { file: files[i], result: e.data } );
				});

				file.upload(new URLRequest(params.url));
			});
		}

		private function eachFile(callback:Function):void {
			var length:Number = browser.fileList.length;
			for (var i:Number = 0; i < length; i++) {
				var file:FileReference = browser.fileList[i];
				callback(file, i);
			}
		}

		private function call(func:String, o:Object):* {
			func = "panda.upload.movies[\"" + params.id + "\"]." + func;
			return ExternalInterface.call(func, o);
		}
	}
}
